//
// Created by yanhai on 2021/3/29.
//

#ifndef CPP_STUDY_TIMEWHEEL_H
#define CPP_STUDY_TIMEWHEEL_H

#include <list>
#include <array>
#include <cstdint>
#include <functional>

#include "spinlock.h"

#define TIME_NEAR_SHIFT 8
#define TIME_NEAR (1 << TIME_NEAR_SHIFT)
#define TIME_LEVEL_SHIFT 6
#define TIME_LEVEL (1 << TIME_LEVEL_SHIFT)
#define TIME_NEAR_MASK (TIME_NEAR-1)
#define TIME_LEVEL_MASK (TIME_LEVEL-1)

struct timer_node {
    uint32_t expire;
    std::function<void(void*)> callback;
    uint8_t cancel;
    void *arg; // 此时携带参数
};

class timer {
public:
    timer();

    // 添加一个定时任务
    // interval秒后，func将会被执行
    // 执行func时，arg将会被传入
    bool add_timer(uint32_t interval,  std::function<void(void*)> func, void *arg);

    void expire_timer();

private:
    void add_node(const timer_node &node);

    void timer_update();

    void dispatch_list(const std::list<timer_node> &list);

    void timer_execute();

    void timer_shift();

    // 重新映射
    void move_list(int level, int idx);

private:
    std::array<std::list<timer_node>, TIME_NEAR> near;
    std::array<std::array<std::list<timer_node>, TIME_LEVEL>, 4> t;
    spinlock lock;
    uint32_t current_time;  // 当前时间
    uint64_t current_point;
};

#endif //CPP_STUDY_TIMEWHEEL_H
